﻿using System.Security.Cryptography;
using System.Text;

namespace 请求响应加密.Tools.Encrypt
{
    public class EncryptHelper
    {
        private static string rawKey = "0123456789abcdefghijklmnopqrstuvwxyz"; 
        private static Random random = new Random();

        // 32字节密钥
        public static string CreateAesKey()
        {
            string key = "";
            for (int i = 0; i < 32; i++)
            {
                key += rawKey[random.Next(0, rawKey.Length)];
            }
            return key;
        }

        // 16字节初始化向量
        public static string CreateAesIV()
        {
            string iv = "";
            for (int i = 0; i < 16; i++)
            {
                iv += rawKey[random.Next(0, rawKey.Length)];
            }
            return iv;
        }

        // 对称加密
        public static string AESEncrypt(string plainText, string aesKey) 
        {
            string[] arr = aesKey.Split("|");
            if (arr.Length != 2)
                throw new Exception("对称密钥必须包含 key | iv");
            return AESEncrypt(plainText, arr[0], arr[1]);
        }


        public static string AESEncrypt(string plainText,string key,string iv)
        {
            using (Aes aesAlg = Aes.Create())
            {
                aesAlg.Key = Encoding.UTF8.GetBytes(key);
                aesAlg.IV = Encoding.UTF8.GetBytes(iv);

                ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

                using (MemoryStream mstream = new MemoryStream())
                {
                    using (CryptoStream csEncrypt = new CryptoStream(mstream, encryptor, CryptoStreamMode.Write))
                    {
                        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                        {
                            swEncrypt.Write(plainText);
                        }
                    }
                    return Convert.ToBase64String(mstream.ToArray());
                }
            }
        }


        public static string AESDecrypt(string cipherText, string aesKey)
        {
            string[] arr = aesKey.Split("|");
            if (arr.Length != 2)
                throw new Exception("对称密钥必须包含 key | iv");
            return AESDecrypt(cipherText, arr[0], arr[1]);
        }


        /// <summary>
        /// 对称解密
        /// </summary>
        /// <param name="cipherText">Base64密文</param>
        /// <returns></returns>
        public static string AESDecrypt(string cipherText, string key, string iv)
        {
            using (Aes aesAlg = Aes.Create())
            {
                aesAlg.Key = Encoding.UTF8.GetBytes(key);
                aesAlg.IV = Encoding.UTF8.GetBytes(iv);
                //aesAlg.Mode = CipherMode.CBC;
                //aesAlg.Padding = PaddingMode.PKCS7;

                ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);

                using (MemoryStream mstream = new MemoryStream(Convert.FromBase64String(cipherText)))
                {
                    using (CryptoStream csDecrypt = new CryptoStream(mstream, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                        {
                            return srDecrypt.ReadToEnd();
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 非对称加密
        /// </summary>
        /// <param name="cipherText">明文内容</param>
        /// <param name="publicKey">公钥</param>
        /// <returns></returns>
        public static string RSAEncrypt(string cipherText, string publicKey)
        {
            try
            {
                byte[] rawBytes = Encoding.UTF8.GetBytes(cipherText);
                byte[] pubytes = Convert.FromBase64String(publicKey);
                using (RSA rsa = RSA.Create())
                {
                    rsa.ImportRSAPublicKey(pubytes, out _);
                    byte[] encrypBytes = rsa.Encrypt(rawBytes, RSAEncryptionPadding.Pkcs1);
                    return Convert.ToBase64String(encrypBytes);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            return null;
        }

        /// <summary>
        /// 对称解密
        /// </summary>
        /// <param name="cipherText">加密数据</param>
        /// <param name="privateKey">私钥</param>
        /// <returns></returns>
        public static string RSADecrypt(string cipherText, string privateKey)
        {
            try
            {
                byte[] encrypBytes = Convert.FromBase64String(cipherText);
                byte[] prbytes = Convert.FromBase64String(privateKey);
                using (RSA rsa = RSA.Create())
                {
                    rsa.ImportRSAPrivateKey(prbytes, out _);
                    byte[] rawBytes = rsa.Decrypt(encrypBytes, RSAEncryptionPadding.Pkcs1);
                    return Encoding.UTF8.GetString(rawBytes);
                }
            }
            catch (Exception e)
            {
                // 日志记录异常信息
                Console.WriteLine(e.Message);
            }
            return null;
        }

        /// <summary>
        /// 生成公私钥
        /// </summary>
        /// <param name="puKey">生成的公钥</param>
        /// <param name="prKey">生成的私钥</param>
        public static void GeneratePubPriKey(out string puKey, out string prKey)
        {
            using (RSA rsa = RSA.Create())
            {
                rsa.KeySize = 2048;
                byte[] prbytes = rsa.ExportRSAPrivateKey();
                byte[] pubytes = rsa.ExportRSAPublicKey();

                puKey = Convert.ToBase64String(pubytes);
                prKey = Convert.ToBase64String(prbytes);

                LogHelper.Info("Public Key: " + Convert.ToBase64String(pubytes));
                LogHelper.Info("Private Key: " + Convert.ToBase64String(prbytes));
            }
        }
    }
}
